package mushystuff.dtb.core.service.pojo;

import java.util.List;

import mushystuff.dtb.core.dao.ProductDAO;
import mushystuff.dtb.core.dao.UserStoryDAO;
import mushystuff.dtb.core.model.Product;
import mushystuff.dtb.core.model.Sprint;
import mushystuff.dtb.core.model.UserStory;
import mushystuff.dtb.core.service.ProductService;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public final class ProductServiceImpl implements ProductService {

	private Log log = LogFactory.getLog(this.getClass());

	private ProductDAO productDAO;

	private UserStoryDAO userStoryDAO;

	@Required
	public void setProductDAO(ProductDAO productDAO) {
		this.productDAO = productDAO;
	}

	@Required
	public void setUserStoryDAO(UserStoryDAO userStoryDAO) {
		this.userStoryDAO = userStoryDAO;
	}

	@Override
	public Product createUpdateProduct(Product product) {
		if (StringUtils.isEmpty(product.getName())) {
			throw new IllegalArgumentException("Name must be set");
		}
		return productDAO.persistProduct(product);
	}

	@Override
	public Product getProduct(long productId) {
		return productDAO.getProduct(productId);
	}

	@Override
	@Transactional(readOnly=true)
	public List<Product> getAllProducts() {
		return productDAO.getAllProducts();
	}
	
	@Override
	@Transactional(readOnly=true)
        public List<Product> getAllActiveProducts() {
                return productDAO.getAllActiveProducts();
        }

	@Override
	public void addUserStoryToBacklog(Product product, UserStory userStory) {
		if (StringUtils.isEmpty(userStory.getStory())) {
			throw new IllegalArgumentException(
					"Story must not be empty for new user story.");
		}
		boolean added = product.getBacklog().add(userStory);
		if (added) {
			userStory.setProduct(product);
			productDAO.persistProduct(product);
		} else {
			log.warn("User Story " + userStory + " not added to product "
					+ product);
			throw new IllegalArgumentException(
					"User Story must have unique story for product");
		}
	}

	@Override
	public void addSprint(Product product, Sprint sprint) {
		if (StringUtils.isEmpty(sprint.getGoal())) {
			throw new IllegalArgumentException(
					"Goal must not be empty for new sprint.");
		}
		boolean added = product.getSprints().add(sprint);
		if (added) {
			sprint.setProduct(product);
			productDAO.persistProduct(product);
		} else {
			log.warn("Sprint " + sprint + " not added to product " + product);
			throw new IllegalArgumentException(
					"Sprint must have unique goal for product");
		}
	}

	@Override
	public void removeUserStoryFromBacklog(long userStoryId) {
		UserStory userStory = userStoryDAO.getUserStory(userStoryId);
		Product product = userStory.getProduct();
		boolean removed = product.getBacklog().remove(userStory);
		if (removed) {
			productDAO.persistProduct(product);
		} else {
			log.warn("User story " + userStory + " not removed from backlog.");
			throw new RuntimeException("User story not removed from backlog.");
		}
	}

	@Override
	public UserStory getUserStory(long userStoryId) {
		return userStoryDAO.getUserStory(userStoryId);
	}



}
